package com.example.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.blog.mapper.AdminMapper;
import com.example.blog.mapper.BlogMapper;
import com.example.blog.mapper.CollectBlogMapper;
import com.example.blog.pojo.Admin;
import com.example.blog.pojo.Blog;
import com.example.blog.pojo.CollectBlog;
import com.example.blog.pojo.Result;
import com.example.blog.service.BlogService;
import com.example.blog.util.TokenUtil.decryptToken;
import com.example.blog.util.TokenUtil.spiltUtils;
import com.example.blog.util.UserUtils.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import static com.example.blog.util.Redis.RedisConstants.BOLG_COLLECT_KEY;
import static com.example.blog.util.Redis.RedisConstants.BOLG_LIKED_KEY;

@Service
@Slf4j
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements BlogService {
    @Resource
    private BlogMapper blogMapper;

    @Resource
    private AdminMapper adminMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private UserUtils userIdUtil;
    @Resource
    private CollectBlogMapper collectBlogMapper;
    private final Lock lock = new ReentrantLock();


    /***
     * 添加博客逻辑
     * @param blog
     * @return 评论结果
     */
    @Override
    @Transactional
    public Result<T> saveBlog(Blog blog, String label, String token) {
        // 解密 token 并获取用户名和昵称
        String pe = decryptToken.decrypt(token);
        String userName = spiltUtils.getUserName(pe);
        String nickname = userIdUtil.getNickname(userName);

        // 检查博客内容是否为空
        if (StringUtils.isEmpty(blog.getContent())) {
            return Result.ACCOUNT();
        }

        // 设置博客信息
        blog.setAuthor(nickname);
        blog.setLabel(label);
        blog.setCreatetime(new Date());
        blog.setStatus(0);
        blog.setPassword(null);

        // 插入博客信息到数据库
        int insert = blogMapper.insert(blog);
        if (insert > 0) {
            return Result.success("发布成功！");
        } else {
            return Result.forbidden("发布失败！");
        }
    }


    /***
     * 根据id查询发布博客
     * @param id
     * @return
     */
    @Override
    @Transactional
    public Result<Blog> getById(int id) {

        QueryWrapper<Blog> wrapper = new QueryWrapper<>();
        wrapper.eq("id", id);
        Blog blog = blogMapper.selectOne(wrapper);
        //返回查询结果
        return Result.success(blog);
    }

    /***
     * 展示博客
     * @return
     */
    @Override
    public Result<Map<String, Object>> showBlog(int pageNum, int pageSize) {
        Page<Blog> page = new Page<>(pageNum, pageSize, true);
        QueryWrapper<Blog> queryWrapper = new QueryWrapper<>();

        IPage<Blog> blogPage = blogMapper.selectPage(page, queryWrapper);

        List<Blog> blogs = blogPage.getRecords();
        long totalcount = blogPage.getTotal();

        // 添加日志
        System.out.println("Total records found: " + totalcount);
        System.out.println("Current page: " + page.getCurrent());
        System.out.println("Total pages: " + page.getPages());

        Map<String, Object> result = new HashMap<>();
        result.put("blogs", blogs);
        result.put("totalcount", totalcount);

        return Result.success(result);
    }

    @Override
    public Result<List<Blog>> getAllBlog() {
        QueryWrapper<Blog> wrapper = new QueryWrapper<>();
        List<Blog> list = blogMapper.selectList(wrapper);
        return Result.success(list);
    }


    /***
     * 展示当前登录用户的博客
     * @param token 获取用户信息
     * @return 用户历史博客
     */
    @Override
    public Result<List<Blog>> getUserBlog(String token) {
        String pe = decryptToken.decrypt(token);
        String userName = spiltUtils.getUserName(pe);
        String nickname = userIdUtil.getNickname(userName);
        QueryWrapper<Blog> wrapper = new QueryWrapper<>();
        wrapper.eq("author", nickname);
        List<Blog> list = blogMapper.selectList(wrapper);
        if (list.isEmpty()) {
            return Result.failed("你还没有发布过博客！");
        }
        return Result.success(list);
    }

    /***
     * 根据标签查询博客
     * @param label
     * @return
     */
    @Override
    public Result<Map<String, Object>> getBlogByLabel(String label, int pageNum, int pageSize) {
        Page<Blog> page = new Page<>(pageNum, pageSize, true);
        QueryWrapper<Blog> wrapper = new QueryWrapper<>();
        wrapper.like("label", label);
        IPage<Blog> blogPage = blogMapper.selectPage(page, wrapper);

        List<Blog> blogs = blogPage.getRecords();
        long totalcount = blogPage.getTotal();

        // 添加日志
        System.out.println("Total records found: " + totalcount);
        System.out.println("Current page: " + page.getCurrent());
        System.out.println("Total pages: " + page.getPages());

        Map<String, Object> result = new HashMap<>();
        result.put("blogs", blogs);
        result.put("total", totalcount);

        return Result.success(result);
    }

    /***
     * 删除博客
     * @param id 评论id
     * @param token 权限查询
     * @return 删除结果
     */
    @Override
    public Result<T> deleteBlogRecord(int id, String token) {
        //解析获取的token数据
        String ps = decryptToken.decrypt(token);
        String password = spiltUtils.getPassWord(ps);
        //通过密码查询管理员信息
        QueryWrapper<Admin> wrapper = new QueryWrapper<>();
        wrapper.eq("password", password);
        List<Admin> list = adminMapper.selectList(wrapper);
        if (list.size() > 0) {
            Blog blog = blogMapper.selectById(id);
            if (blog == null) {
                return Result.failed("该博客不存在！");
            }
            String coverImgPath = blog.getCoverurl();
            String imageName = coverImgPath.substring(coverImgPath.lastIndexOf("/") + 1);
            int delete = blogMapper.deleteById(id);
            if (delete > 0) {
                File file = new File("upload/" + imageName);
                if (file.exists()) {
                    boolean deleteResult = file.delete();
                    if (deleteResult) {
                        return Result.success("删除成功！");
                    }
                    return Result.failed("删除失败！");
                }
            }
        }
        return Result.failed("没有权限！");
    }

    /***
     * 根据作者查询博客
     * @return
     */
    @Override
    public Result<List<Blog>> getBlogsByAuthor(String author) {
        QueryWrapper<Blog> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("author", author);
        List<Blog> selectList = blogMapper.selectList(queryWrapper);
        if (selectList.isEmpty()) {
            return Result.failed("此用户没有发布过任何博客！");
        }
        return Result.success(selectList);
    }

    /***
     * 根据关键词
     * @param keyword 评论的关键词
     * @return 查询出来的评论
     */
    @Override
    public Result<Map<String, Object>> getByKeyword(String keyword, int pageNum, int pageSize) {
        Page<Blog> page = new Page<>(pageNum, pageSize, true);
        QueryWrapper<Blog> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("content", keyword).or().like("title", keyword);
        IPage<Blog> blogPage = blogMapper.selectPage(page, queryWrapper);

        List<Blog> blogs = blogPage.getRecords();
        long total = blogPage.getTotal();

        // 添加日志
        System.out.println("Total records found: " + total);
        System.out.println("Current page: " + page.getCurrent());
        System.out.println("Total pages: " + page.getPages());

        Map<String, Object> result = new HashMap<>();
        result.put("blogs", blogs);
        result.put("total", total);

        return Result.success(result);


    }

    /***
     * 点赞功能
     * @param id 点赞评论id
     * @return 点赞数据
     */
    @Override
    public Result<T> likeBlogs(int id, String token) {
        try {
            String pe = decryptToken.decrypt(token);
            if (pe == null || pe.isEmpty()) {
                return Result.failed("无效的token！");
            }

            String userName = spiltUtils.getUserName(pe);
            if (userName.isEmpty()) {
                return Result.failed("无法获取用户名！");
            }

            Integer userId = userIdUtil.getUserId(userName);
            if (userId == null) {
                return Result.failed("无法获取用户ID！");
            }

            lock.lock(); // 上锁
            try {
                String key = BOLG_LIKED_KEY + id;
                Boolean isMember = stringRedisTemplate.opsForSet().isMember(key, String.valueOf(userId));
                if (Boolean.FALSE.equals(isMember)) {
                    // 如果未点赞
                    boolean isSuccess = update().setSql("likes=likes+1").eq("id", id).update();
                    if (isSuccess) {
                        stringRedisTemplate.opsForSet().add(key, String.valueOf(userId));
                        return Result.success("点赞成功！");
                    }
                } else {
                    // 如果点赞过了
                    update().setSql("likes=likes-1").eq("id", id).update();
                    stringRedisTemplate.opsForSet().remove(key, String.valueOf(userId));
                    return Result.success("已取消点赞！");
                }
            } finally {
                lock.unlock(); // 解锁
            }

            return Result.failed("登录后才可以点赞！");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

        /**
     * 收藏模块
     *
     * @return 收藏结果
     */
    @Override
    public Result<T> CollectBlog(int blogId, String token) {
        String pe = decryptToken.decrypt(token);
        String userName = spiltUtils.getUserName(pe);
        //获取登录用户id
        Integer userId = userIdUtil.getUserId(userName);
        //上锁
        lock.lock();
        try {
            //判断用户是否收藏过
            String key = BOLG_COLLECT_KEY + blogId;
            Boolean isMember = stringRedisTemplate.opsForSet().isMember(key, String.valueOf(userId));
            if (Boolean.FALSE.equals(isMember)) {
                CollectBlog collectBlog = new CollectBlog();
                collectBlog.setUserId(userId);
                collectBlog.setBlogId(blogId);
                int insert = collectBlogMapper.insert(collectBlog);
                if (insert > 0) {
                    stringRedisTemplate.opsForSet().add(key, String.valueOf(userId));
                    return Result.success("收藏成功！");
                }
            } else {
                QueryWrapper<CollectBlog> wrapper = new QueryWrapper<>();
                wrapper.eq("blogId", blogId).eq("userId", userId);
                int delete = collectBlogMapper.delete(wrapper);
                if (delete > 0) {
                    stringRedisTemplate.opsForSet().remove(key, String.valueOf(userId));
                    return Result.success("已取消收藏！");
                }
            }

        } finally {
            lock.unlock(); // 解锁
        }

        return Result.failed("登录后才可以点赞！");
    }
}
